
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package action;

import collection.Products;
import dao.CategoryDAO;
import dao.ProductDAO;
import dto.Category;
import dto.Image;
import dto.Product;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import util.ServerValidation;
import util.StringUtil;
import util.XMLUtil;

/**

 *

 * @author Thinh

 */
public class AdminProductController extends BaseController implements ServletRequestAware {

    ProductDAO productDAO;
    CategoryDAO categoryDAO;
    Products productsUtil;
    private Log log;
    private String productXMLFilePath;
    private String productXSLFilePath;
    private String productSchemaFilePath;
    private InputStream inputStream;
    private String resultStream;
    private String updatedProduct;
    private HttpServletRequest servletRequest;
    private File file;
    private String fileName;
    private List<Category> categories;
    private Product product;
    private int category;
    private String images;
    private String folderImage;
    private String productId;
    private boolean isShowed;

    public AdminProductController() {
        super();
        log = LogFactory.getLog(ProductController.class);
        productXMLFilePath = System.getProperty("rootPath") + util.StringUtil.XML_FOLDER_PATH + "products.xml";
        productXSLFilePath = System.getProperty("rootPath") + util.StringUtil.XSL_FOLDER_PATH + "productTable.xsl";
        productSchemaFilePath = System.getProperty("rootPath") + util.StringUtil.XML_FOLDER_PATH + "product.xsd";
        productDAO = new ProductDAO(Product.class);
        categoryDAO = new CategoryDAO(Category.class);
        folderImage = "../productImage/";
        productsUtil = new Products();
    }

    public String loadProduct() {
        if (ServerValidation.isGuest()) {
            return LOGIN;
        } else if (ServerValidation.isCustomer()) {
            return StringUtil.INVALID_ROLE;
        } else {
            categoryDAO.openSession();
            setCategories(categoryDAO.all());
            categoryDAO.closeSession();
            return SUCCESS;
        }

    }

    public String getXSLFile() {
        if (ServerValidation.isGuest()) {
            return LOGIN;
        } else if (ServerValidation.isCustomer()) {
            return StringUtil.INVALID_ROLE;
        } else {
            try {
                File f = new File(productXSLFilePath);
                setInputStream(new FileInputStream(f));
            } catch (FileNotFoundException ex) {
                Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                return ERROR;
            }
            return SUCCESS;
        }
    }

    public String receiveXMLDoc() {
        if (ServerValidation.isGuest()) {
            return LOGIN;
        } else if (ServerValidation.isCustomer()) {
            return StringUtil.INVALID_ROLE;
        } else {
            if (getResultStream() != null) {
                try {
                    InputSource source = new InputSource(new StringReader(getResultStream()));
                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                    dbf.setNamespaceAware(true);
                    DocumentBuilder db = dbf.newDocumentBuilder();
                    Document doc = db.parse(source);

                    JAXBContext context = JAXBContext.newInstance(Products.class);
                    Products listUpdatedProducts = (Products) XMLUtil.unmarshallObject(context, doc);

                    //Receive id's users updated
                    String[] idUpdatedProduct = updatedProduct.split(",");
                    Product updatedProduct;
                    for (int i = 0; i < idUpdatedProduct.length; ++i) {
                        int updatedProductId = Integer.parseInt(idUpdatedProduct[i]);
                        updatedProduct = listUpdatedProducts.getProductById(updatedProductId);
                        productDAO.openSession();
                        productDAO.updateProduct(updatedProduct);
                        productDAO.closeSession();
                    }

                    //Write to xml
                    XMLUtil.writeXML(doc, productXMLFilePath);

                    return SUCCESS;

                } catch (TransformerConfigurationException ex) {
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (UnsupportedEncodingException ex) {
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (TransformerException ex) {
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SAXException ex) {
                    System.out.println("XSD occurs errors: " + ex);
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (Exception ex) {
                    System.out.println("XSD occurs errors: " + ex);
                    Logger.getLogger(AdminController.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
            return ERROR;
        }
    }

    public String addNewProduct() {
        if (ServerValidation.isGuest()) {
            return LOGIN;
        } else if (ServerValidation.isCustomer()) {
            return StringUtil.INVALID_ROLE;
        } else {
            if (product != null) {
                try {
                    productDAO.openSession();
                    product.setIsDeleted(false);
                    System.out.println("[AddNewProduct]ProductIsShowed: " + product.isIsShowed());
                    //Get category
                    categoryDAO.openSession();
                    Category loadedCategory = categoryDAO.get(category);

                    if (loadedCategory != null) {
                        product.setCategory(loadedCategory);
                    }
                    Calendar cal = Calendar.getInstance();
                    Date currentDate = cal.getTime();
                    product.setCreateDate(currentDate);
                    product.setUpdateDate(currentDate);
                    //Assign image url
                    String productImages = images;
                    Image newImage;
                    List<Image> listImage = new ArrayList<Image>();
//                for (String image : productImages) {
                    if (!images.equals("")) {
                        newImage = new Image();
                        newImage.setName(images);
                        newImage.setUrl(folderImage + images);
                        newImage.setDescription(images);
                        newImage.setProduct(product);
                        newImage.setIsBigsize(false);
                        listImage.add(newImage);
                    }
//                }
                    if (!listImage.isEmpty()) {
                        product.setImages(listImage);
                    } else {
                        //set default image
                        String defaultImageName = "default.jpg";
                        newImage = new Image();
                        newImage.setName(defaultImageName);
                        newImage.setUrl(folderImage + defaultImageName);
                        newImage.setDescription(defaultImageName);
                        newImage.setProduct(product);
                        newImage.setIsBigsize(false);
                        listImage.add(newImage);
                        product.setImages(listImage);
                    }
                    productDAO.save(product);
                    categoryDAO.closeSession();
                    productDAO.closeSession();
                    //Save new node product to xml doc
                    Document productDoc = XMLUtil.parserDOMXML(productXMLFilePath);
                    productsUtil.addProductNode(productDoc, product);
//
//                //Write doc to xml
                    XMLUtil.writeXML(productDoc, productXMLFilePath);
                    return SUCCESS;
                } catch (TransformerConfigurationException ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (TransformerException ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ParserConfigurationException ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SAXException ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                } catch (Exception ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return ERROR;
    }

    public String deleteProduct() {
        if (ServerValidation.isGuest()) {
            return LOGIN;
        } else if (ServerValidation.isCustomer()) {
            return StringUtil.INVALID_ROLE;
        } else {
            try {
                Document doc = XMLUtil.parserDOMXML(productXMLFilePath);

                productsUtil.deleteProductNode(doc, productId);

                int iproductId = Integer.parseInt(productId);

                productDAO.openSession();
                if (productDAO.deleteProductById(iproductId)) {
                    productDAO.closeSession();
                    XMLUtil.writeXML(doc, productXMLFilePath);
                    inputStream = new ByteArrayInputStream(StringUtil.OK.getBytes());
                } else {
                    inputStream = new ByteArrayInputStream(StringUtil.CANCELLED.getBytes());
                }
                return SUCCESS;
            } catch (ParserConfigurationException ex) {
                Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SAXException ex) {
                Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
            } catch (Exception ex) {
                Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
            }
            return ERROR;
        }
    }

    /**
     * @return the inputStream
     */
    public InputStream getInputStream() {
        return inputStream;
    }

    public String uploadImage() {
        if (ServerValidation.isGuest()) {
            return LOGIN;
        } else if (ServerValidation.isCustomer()) {
            return StringUtil.INVALID_ROLE;
        } else {
            if (file != null) {
                try {
                    String imageFilePath = System.getProperty("rootPath") + StringUtil.IMAGE_PRODUCT_PATH + fileName;
                    File theFile = new File(imageFilePath);
                    if (!theFile.exists()) {
                        FileUtils.copyFile(file, theFile);
                    }
                    return SUCCESS;
                } catch (IOException ex) {
                    Logger.getLogger(AdminProductController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return ERROR;
    }

    /**
     * @param inputStream the inputStream to set
     */
    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    /**
     * @return the resultStream
     */
    public String getResultStream() {
        return resultStream;
    }

    /**
     * @param resultStream the resultStream to set
     */
    public void setResultStream(String resultStream) {
        this.resultStream = resultStream;
    }

    /**
     * @return the updatedProduct
     */
    public String getUpdatedProduct() {
        return updatedProduct;
    }

    /**
     * @param updatedProduct the updatedProduct to set
     */
    public void setUpdatedProduct(String updatedProduct) {
        this.updatedProduct = updatedProduct;
    }

    public void setServletRequest(HttpServletRequest hsr) {
        servletRequest = hsr;
    }

    /**
     * @return the file
     */
    public File getFile() {
        return file;
    }

    /**
     * @param file the file to set
     */
    public void setFile(File file) {
        this.file = file;
    }

    /**
     * @return the fileName
     */
    public String getFileName() {
        return fileName;
    }

    /**
     * @param fileName the fileName to set
     */
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    /**
     * @return the categories
     */
    public List<Category> getCategories() {
        return categories;
    }

    /**
     * @param categories the categories to set
     */
    public void setCategories(List<Category> categories) {
        this.categories = categories;
    }

    /**
     * @return the product
     */
    public Product getProduct() {
        return product;
    }

    /**
     * @param product the product to set
     */
    public void setProduct(Product product) {
        this.product = product;
    }

    /**
     * @return the category
     */
    public int getCategory() {
        return category;
    }

    /**
     * @param category the category to set
     */
    public void setCategory(int category) {
        this.category = category;
    }

    /**
     * @return the images
     */
    public String getImages() {
        return images;
    }

    /**
     * @param images the images to set
     */
    public void setImages(String images) {
        this.images = images;
    }

    /**
     * @return the isShowed
     */
    public boolean isIsShowed() {
        return isShowed;
    }

    /**
     * @param isShowed the isShowed to set
     */
    public void setIsShowed(boolean isShowed) {
        this.isShowed = isShowed;
    }

    /**
     * @return the productId
     */
    public String getProductId() {
        return productId;
    }

    /**
     * @param productId the productId to set
     */
    public void setProductId(String productId) {
        this.productId = productId;
    }
    /**
     * @return the filename
     */
}
